package com.lysj.bhp.api.controller;

import com.lysj.bhp.api.base.ApiContent;
import com.lysj.bhp.exchangerate.domain.ExchangeRate;
import com.lysj.bhp.exchangerate.vo.MyBalanceVo;
import com.lysj.bhp.investment.domain.Reward;
import com.lysj.bhp.recharge.domain.RechargeRecord;
import com.lysj.bhp.user.domain.User;
import com.lysj.bhp.util.web.ParamUtil;
import com.lysj.bhp.util.web.Resp;
import com.lysj.bhp.wallet.domain.BhpcWallet;
import com.lysj.bhp.wallet.domain.BitCoinWallet;
import com.lysj.bhp.wallet.domain.EthereumWallet;
import com.lysj.bhp.wallet.vo.BhpcInfoVo;
import com.lysj.bhp.wallet.vo.WalletVo;
import com.lysj.bhp.withdraw.domain.Poundage;
import com.lysj.bhp.withdraw.domain.WithDraw;
import com.lysj.bhp.withdraw.domain.WithDrawAddress;
import com.lysj.bhp.withdraw.vo.WithDrawRecordVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

@RestController
@RequestMapping("/api/v2/user")
@Api(value = "AccountBalanceController", tags = "我的资产模块接口")
public class ApiAccountBalanceController extends ApiContent {

    private ExchangeRate exchangeRate = ExchangeRate.getInstance();
    /**
     * @author drj
     * @date 2018/05/21 15:41
     * @Description: 我的资产显示总资产, BHPC收益, 用户所有钱包余额信息
     */
    //  登录相关接口
    @ApiOperation(value = "我的资产")
    @GetMapping("/my_balance")
    public Resp myBalance() {
        Map<String, Object> map = new HashMap<>();
        //获取用户的所有钱包
        BitCoinWallet bitCoinWallet = bitcoinWalletRepository.findByUserId(currentUser().getUserId());
        EthereumWallet ethereumWallet = ethereumWalletRepository.findByUserId(currentUser().getUserId());
        BhpcWallet bhpcWallet = bhpcWalletRepository.findByUserId(currentUser().getUserId());

        //显示所有钱包的可用余额
        BigDecimal bitBalance = BigDecimal.valueOf(0);
        BigDecimal ethBalance = BigDecimal.valueOf(0);
        BigDecimal bhpcBalance = BigDecimal.valueOf(0);
        //把所有余额转化成美元
        if (null != bitCoinWallet) {
            bitBalance = bitCoinWallet.getAvailBalance().multiply(exchangeRate.getBITCOIN_TO_DOLLAR());
        }
        if (null != ethereumWallet) {
            ethBalance = ethereumWallet.getAvailBalance().multiply(exchangeRate.getETHEREUM_TO_DOLLAR());
        }
        if (null != bhpcWallet) {
            bhpcBalance = bhpcWallet.getAvailBalance().multiply(exchangeRate.getBHPC_TO_DOLLAR());
        }
        BigDecimal totalDollar = bitBalance.add(ethBalance).add(bhpcBalance).setScale(6, BigDecimal.ROUND_HALF_UP);

        //把美元转化成CNY和比特币
        BigDecimal totalCny = totalDollar.multiply(exchangeRate.getDOLLAR_TO_CNY().setScale(6, BigDecimal.ROUND_HALF_UP));
        BigDecimal totalBtc = totalDollar.divide(exchangeRate.getBITCOIN_TO_DOLLAR(), 6, BigDecimal.ROUND_HALF_UP);
        //构建一个Vo,显示总资产跟算力币兑换比特币跟ETH汇率
        MyBalanceVo myBalanceVo = new MyBalanceVo();
        myBalanceVo.setTotalCny(totalCny);
        myBalanceVo.setTotalBtc(totalBtc);
        myBalanceVo.setBhpc2btc(exchangeRate.getBHPC_TO_DOLLAR().divide(exchangeRate.getBITCOIN_TO_DOLLAR(), 6, BigDecimal.ROUND_HALF_UP));
        myBalanceVo.setBhpc2eth(exchangeRate.getBHPC_TO_DOLLAR().divide(exchangeRate.getETHEREUM_TO_DOLLAR(), 6, BigDecimal.ROUND_HALF_UP));
        myBalanceVo.setTotalDollar(totalDollar);
        map.put("myBalanceVo", myBalanceVo);

        //显示用户BHPC收益信息
        Reward reward = rewardRepository.findByUserIdAndType(currentUser().getUserId(), 100);


        BigDecimal btcToDollar = exchangeRate.getBITCOIN_TO_DOLLAR();
        BigDecimal dollarToCnyRate = exchangeRate.getDOLLAR_TO_CNY();

        //获取以太坊对人民币的汇率
        BigDecimal ethToCny = exchangeRate.getETH_TO_CNY();
        //获取以太坊对美元的汇率
        BigDecimal ethereumToDollar = exchangeRate.getETHEREUM_TO_DOLLAR();

        BhpcInfoVo bhpcInfoVo = new BhpcInfoVo();
        if (!ParamUtil.isBlack(bhpcWallet)) {
            //余额CNY为单位
            bhpcInfoVo.setBalance(bhpcWallet.getAvailBalance().multiply(exchangeRate.getBHPC_TO_DOLLAR()).multiply(dollarToCnyRate).setScale(6, BigDecimal.ROUND_DOWN));
            //余额美元为单位
            bhpcInfoVo.setBalance(bhpcWallet.getAvailBalance().multiply(exchangeRate.getBHPC_TO_DOLLAR().setScale(6, BigDecimal.ROUND_DOWN)));
        } else {
            //余额CNY为单位
            bhpcInfoVo.setBalance(new BigDecimal(BigInteger.ZERO));
            //余额美元为单位
            bhpcInfoVo.setBalance(new BigDecimal(BigInteger.ZERO));
        }
        //计算用户的利息

        //用户旧数据以ETH为单位
        BigDecimal ethDivided = currentUser().getDividend();

        //总利息Eth为单位
        BigDecimal totalDivided = ethDivided;

        //总利息Eth为单位
        bhpcInfoVo.setBtcDividend(totalDivided.setScale(6, BigDecimal.ROUND_DOWN));
        //累计收益CNY为单位
        bhpcInfoVo.setCnyDividend(totalDivided.multiply(ethToCny).setScale(6, BigDecimal.ROUND_DOWN));
        //累计收益DOLLAR为单位
        bhpcInfoVo.setDollarDividend(totalDivided.multiply(ethereumToDollar).setScale(6, BigDecimal.ROUND_DOWN));

        //昨日利息CNY为单位
        bhpcInfoVo.setLastDividend(((dividendController.lastDividend(new Date(), currentUser().getUserId())).multiply(ethToCny)).setScale(6, BigDecimal.ROUND_DOWN));
        //昨日利息DOLLAR为单位
        bhpcInfoVo.setLastDividendDollar((dividendController.lastDividend(new Date(), currentUser().getUserId())).multiply(ethereumToDollar).setScale(6, BigDecimal.ROUND_DOWN));


        if (null != reward) {
            //用户奖励
            bhpcInfoVo.setReward(reward.getAvailBalance().setScale(6, BigDecimal.ROUND_DOWN)); //奖励BHPC
            if (!ParamUtil.isBlack(bhpcWallet)) {
                //本金CNY为单位
                bhpcInfoVo.setCnyPrincipal((bhpcWallet.getAvailBalance().add(reward.getAvailBalance())).multiply(exchangeRate.getBHPC_TO_DOLLAR()).multiply(exchangeRate.getDOLLAR_TO_CNY()).setScale(6, BigDecimal.ROUND_DOWN));
                //本金美元为单位
                bhpcInfoVo.setDollarPrincipal((bhpcWallet.getAvailBalance().add(reward.getAvailBalance())).multiply(exchangeRate.getBHPC_TO_DOLLAR()).setScale(6, BigDecimal.ROUND_DOWN));
            } else {
                //本金CNY为单位
                bhpcInfoVo.setCnyPrincipal(reward.getAvailBalance().multiply(exchangeRate.getBHPC_TO_DOLLAR()).multiply(exchangeRate.getDOLLAR_TO_CNY()).setScale(6, BigDecimal.ROUND_DOWN));
                //本金美元为单位
                bhpcInfoVo.setDollarPrincipal(reward.getAvailBalance().multiply(exchangeRate.getBHPC_TO_DOLLAR()).setScale(6, BigDecimal.ROUND_DOWN));
            }
        } else {
            //用户奖励
            bhpcInfoVo.setReward(new BigDecimal(BigInteger.ZERO));
            if (!ParamUtil.isBlack(bhpcWallet)) {
                //本金CNY为单位
                bhpcInfoVo.setCnyPrincipal(bhpcWallet.getAvailBalance().multiply(exchangeRate.getBHPC_TO_DOLLAR()).multiply(exchangeRate.getDOLLAR_TO_CNY()).setScale(6, BigDecimal.ROUND_DOWN));
                //本金美元为单位
                bhpcInfoVo.setDollarPrincipal(bhpcWallet.getAvailBalance().multiply(exchangeRate.getBHPC_TO_DOLLAR()).setScale(6, BigDecimal.ROUND_DOWN));
            } else {
                //本金CNY为单位
                bhpcInfoVo.setCnyPrincipal(new BigDecimal(BigInteger.ZERO));
                //本金美元为单位
                bhpcInfoVo.setDollarPrincipal(new BigDecimal(BigInteger.ZERO));
            }
        }
        map.put("bhpcInfoVo", bhpcInfoVo);
        //创建返回的钱包
        List<WalletVo> walletVos = new LinkedList<>();
        WalletVo bitcoinWallteVo = new WalletVo();
        WalletVo ethereumWalletVo = new WalletVo();
        WalletVo bhpcWalletVo = new WalletVo();
        bitcoinWallteVo.setType(10);
        bitcoinWallteVo.setName("BTC");
        bitcoinWallteVo.setChineseName("比特币");
        ethereumWalletVo.setType(20);
        ethereumWalletVo.setName("ETH");
        ethereumWalletVo.setChineseName("以太坊");
        bhpcWalletVo.setType(100);
        bhpcWalletVo.setName("BHPC");
        bhpcWalletVo.setChineseName("算力现金");
        if (null != bitCoinWallet) {
            bitcoinWallteVo.setTotalBalance(bitCoinWallet.getBalance().setScale(6, BigDecimal.ROUND_DOWN));
            bitcoinWallteVo.setAvailBalance(bitCoinWallet.getAvailBalance().setScale(6, BigDecimal.ROUND_DOWN));
            bitcoinWallteVo.setFreezeBalance(bitCoinWallet.getFreezeBalance().setScale(6, BigDecimal.ROUND_DOWN));
            bitcoinWallteVo.setRewardBalance(new BigDecimal(BigInteger.ZERO));
        } else {
            bitcoinWallteVo.setTotalBalance(new BigDecimal(BigInteger.ZERO));
            bitcoinWallteVo.setAvailBalance(new BigDecimal(BigInteger.ZERO));
            bitcoinWallteVo.setFreezeBalance(new BigDecimal(BigInteger.ZERO));
            bitcoinWallteVo.setRewardBalance(new BigDecimal(BigInteger.ZERO));
        }
        if (null != ethereumWallet) {
            ethereumWalletVo.setTotalBalance(ethereumWallet.getBalance().setScale(6, BigDecimal.ROUND_DOWN));
            ethereumWalletVo.setAvailBalance(ethereumWallet.getAvailBalance().setScale(6, BigDecimal.ROUND_DOWN));
            ethereumWalletVo.setFreezeBalance(ethereumWallet.getFreezeBalance().setScale(6, BigDecimal.ROUND_DOWN));
            ethereumWalletVo.setRewardBalance(new BigDecimal(BigInteger.ZERO));
        } else {
            ethereumWalletVo.setTotalBalance(new BigDecimal(BigInteger.ZERO));
            ethereumWalletVo.setAvailBalance(new BigDecimal(BigInteger.ZERO));
            ethereumWalletVo.setFreezeBalance(new BigDecimal(BigInteger.ZERO));
            ethereumWalletVo.setRewardBalance(new BigDecimal(BigInteger.ZERO));
        }
        if (null != bhpcWallet) {
            if (null != reward) {
                bhpcWalletVo.setTotalBalance(bhpcWallet.getBalance().add(reward.getBalance()).setScale(6, BigDecimal.ROUND_DOWN));
                bhpcWalletVo.setAvailBalance(bhpcWallet.getAvailBalance().setScale(6, BigDecimal.ROUND_DOWN));
                bhpcWalletVo.setFreezeBalance(bhpcWallet.getFreezeBalance().add(reward.getFreezeBalance()).setScale(6, BigDecimal.ROUND_DOWN));
                bhpcWalletVo.setRewardBalance(reward.getAvailBalance().setScale(6, BigDecimal.ROUND_DOWN));
            } else {
                bhpcWalletVo.setTotalBalance(bhpcWallet.getBalance().setScale(6, BigDecimal.ROUND_DOWN));
                bhpcWalletVo.setAvailBalance(bhpcWallet.getAvailBalance().setScale(6, BigDecimal.ROUND_DOWN));
                bhpcWalletVo.setFreezeBalance(bhpcWallet.getFreezeBalance().setScale(6, BigDecimal.ROUND_DOWN));
                bhpcWalletVo.setRewardBalance(new BigDecimal(BigInteger.ZERO));
            }
        } else {
            if (null != reward) {
                bhpcWalletVo.setTotalBalance(reward.getAvailBalance().setScale(6, BigDecimal.ROUND_DOWN));
                bhpcWalletVo.setAvailBalance(new BigDecimal(BigInteger.ZERO));
                bhpcWalletVo.setFreezeBalance(new BigDecimal(BigInteger.ZERO));
                bhpcWalletVo.setRewardBalance(reward.getAvailBalance().setScale(6, BigDecimal.ROUND_DOWN));
            } else {
                bhpcWalletVo.setTotalBalance(new BigDecimal(BigInteger.ZERO));
                bhpcWalletVo.setAvailBalance(new BigDecimal(BigInteger.ZERO));
                bhpcWalletVo.setFreezeBalance(new BigDecimal(BigInteger.ZERO));
                bhpcWalletVo.setRewardBalance(new BigDecimal(BigInteger.ZERO));
            }

        }
        walletVos.add(bitcoinWallteVo);
        walletVos.add(ethereumWalletVo);
        walletVos.add(bhpcWalletVo);
        map.put("walletVos", walletVos);
        map.put("status", ParamUtil.isBlack(currentUser().getTradePassword()) ? 1 : 0);
        return new Resp(map);
    }


    /**
     * @author drj
     * @date 2018/05/21 15:41
     * @Description:在我的资产界面,用户点击充币,显示对应的钱包地址跟最新5条充币记录
     */
    @ApiOperation(value = "充值,显示钱包地址跟最新5条充值信息", notes = "需要钱包类型,type 10:比特币;20:以太坊;100:BHPC")
    @GetMapping("/recharge")
    public Resp recharge(int type) throws Exception {
        Map<String, Object> map = new HashMap<>();
        Resp resp = new Resp("");
        //获取最新的5条充值记录
        List<RechargeRecord> rechargeRecordList = new ArrayList<>();
        PageRequest pr = new PageRequest(0, 5);
        rechargeRecordList = rechargeRecordRepository.findByUserIdAndCoinTypeOrderByCreateTimeDesc(currentUser().getUserId(), type, pr);
        map.put("rechargeRecordList", rechargeRecordList);
        User user = userRepository.findByUserId(currentUser().getUserId());
        switch (type) {  //10:比特币;20:以太坊;100:BHPC
            case 10:
                resp = bitcoinWalletController.myBitcoinWallet(user.getEmail());
                map.put("address", resp.getObj());
                break;
            case 20:
                resp = ethereumWalletController.myEthereumWallet();
                map.put("address", resp.getObj());
                break;
            case 100:
                resp = bhpcWalletController.myBhpcWallet();
                map.put("address", resp.getObj());
                break;
        }
        return new Resp(map);
    }


    /**
     * @author drj
     * @date 2018/05/21 19:30
     * @Description:在我的资产界面,用户点击提币,显示对应的币种的提币地址跟钱包的可用余额,以及最新5条提币记录
     */
    @ApiOperation(value = "提币,显示对应钱包提币地址跟钱包可用余额,最新5条提币信息", notes = "需要钱包类型,type 10:比特币;20:以太坊;100:BHPC")
    @GetMapping("/withdraw")
    public Resp withdraw(int type) {  //10:比特币;20:以太坊;100:BHPC;
        Map<String, Object> map = new HashMap<>();
        //获取用户提币地址
        List<WithDrawAddress> withDrawAddressList = new ArrayList<>();
        if (ParamUtil.isBlack(type)) {
            return new Resp(Resp.PARAM_ERROR, "系统错误");
        }
        withDrawAddressList = withDrawAddressRepository.findByUserIdAndTypeAndStatus(currentUser().getUserId(), type, 1);
        map.put("withDrawAddressVos", withDrawAddressList);
        Poundage poundage = poundageRepository.findByType(type);
        if (null != poundage) {
            map.put("poundage", poundage.getTransferFee());
            map.put("miniNumber",poundage.getMiniNumber());
            map.put("maxNumber",poundage.getMaxNumber());
        } else {
            map.put("poundage", 0);
            map.put("miniNumber", 0);
            map.put("maxNumber", 0);
        }

        //查询对应钱包的可用余额
        if (10 == type) {
            BitCoinWallet bitCoinWallet = bitcoinWalletRepository.findByUserId(currentUser().getUserId());
            if (!ParamUtil.isBlack(bitCoinWallet)) {
                map.put("availBalance", bitCoinWallet.getAvailBalance());
            } else {
                map.put("availBalance", new BigDecimal(BigInteger.ZERO));
            }
        } else if (20 == type) {
            EthereumWallet ethereumWallet = ethereumWalletRepository.findByUserId(currentUser().getUserId());
            if (!ParamUtil.isBlack(ethereumWallet)) {
                map.put("availBalance", ethereumWallet.getAvailBalance());
            } else {
                map.put("availBalance", new BigDecimal(BigInteger.ZERO));
            }
        } else if (100 == type) {
            BhpcWallet bhpcWallet = bhpcWalletRepository.findByUserId(currentUser().getUserId());
            if (!ParamUtil.isBlack(bhpcWallet)) {
                map.put("availBalance", bhpcWallet.getAvailBalance());
            } else {
                map.put("availBalance", new BigDecimal(BigInteger.ZERO));
            }
            Reward reward = rewardRepository.findByUserId(currentUser().getUserId());
            if (!ParamUtil.isBlack(reward)) {
                map.put("reward", reward.getAvailBalance());
            }else{
                map.put("reward", new BigDecimal(BigInteger.ZERO));
            }
        }
        //查询最新的5条提币记录
        List<WithDrawRecordVo> withDrawRecordVos = new LinkedList<>();
        PageRequest pr = new PageRequest(0, 5);
        if (type == 100) {
            Integer[] typeIds = new Integer[2];
            typeIds[0] = type;
            typeIds[1] = 110;
            List<WithDraw> withDrawList = withdrawRepository.findByUserIdAndTypeInOrderByCreateDateDesc(currentUser().getUserId(), typeIds, pr);
            for (WithDraw withDraw : withDrawList) {
                WithDrawRecordVo withDrawRecordVo = new WithDrawRecordVo();
                withDrawRecordVo.setAddress(withDraw.getAddress());
                withDrawRecordVo.setTransferAmount(withDraw.getAmount());
                withDrawRecordVo.setActualAmount(withDraw.getAmount().subtract(withDraw.getFeeAmount()));
                withDrawRecordVo.setCreateDate(withDraw.getCreateDate());
                withDrawRecordVo.setCheckStatus(withDraw.getCheckStatus());
                withDrawRecordVos.add(withDrawRecordVo);
            }
        } else {
            List<WithDraw> withDrawList = withdrawRepository.findByUserIdAndTypeOrderByCreateDateDesc(currentUser().getUserId(), type, pr);
            for (WithDraw withDraw : withDrawList) {
                WithDrawRecordVo withDrawRecordVo = new WithDrawRecordVo();
                withDrawRecordVo.setAddress(withDraw.getAddress());
                withDrawRecordVo.setTransferAmount(withDraw.getAmount());
                withDrawRecordVo.setActualAmount(withDraw.getAmount().subtract(withDraw.getFeeAmount()));
                withDrawRecordVo.setCreateDate(withDraw.getCreateDate());
                withDrawRecordVo.setCheckStatus(withDraw.getCheckStatus());
                withDrawRecordVos.add(withDrawRecordVo);
            }
        }
        map.put("withDrawRecordVos", withDrawRecordVos);
        return new Resp(map);
    }

}
